package mapEditor.utils;

import debug.*;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Stroke;
import java.awt.Shape;
import java.awt.geom.GeneralPath;
import java.util.Vector;

import javax.swing.border.Border;
import javax.swing.border.TitledBorder;

public class Util
{
	
  // Example: round(23.45678912345,100) ==> 23.46	
  public static double round(double x,int d)
  { double rounded=((double)Math.round(x*d))/d;
    //System.out.println("ROUND: "+x+"  ==>  "+rounded+", Math.round(x*d)="+Math.round(x*d));
	return(rounded);
  }
  
  public static void paint(Graphics2D g,Shape shape,SvgFill svgFill,SvgStroke svgStroke)
  { if(shape==null) return;
	if(svgFill!=null) if(svgFill.getEnabled()) fill(g,shape,svgFill.getRGBAColor());
    if(svgStroke!=null) if(svgStroke.getEnabled()) draw(g,shape,svgStroke.getRGBAColor(),svgStroke.getBasicStroke());
  }
  
  public static void drawString(Graphics2D g,String str,float x,float y,SvgFont svgFont,SvgFill svgFill,SvgStroke svgStroke)
  { //if(color==null) return;
    //if(stroke==null) stroke=new BasicStroke(1);
	Font oldFont=g.getFont();
	Color oldColor=g.getColor();
    Stroke oldStroke=g.getStroke();
    g.setFont(svgFont.getFont());
//  g.setColor(svgFill.getRGBAColor());
    g.setColor(svgStroke.getRGBAColor());
    g.setStroke(svgStroke.getBasicStroke());
	g.drawString(str,x,y);
	g.setFont(oldFont); 
	g.setColor(oldColor); 
    g.setStroke(oldStroke);
  }
  
  public static void draw(Graphics2D g,Shape shape,Color color,Stroke stroke)
  { if(color==null) return;
    if(stroke==null) stroke=new BasicStroke(1);
	Color oldColor=g.getColor();
    Stroke oldStroke=g.getStroke();
    g.setColor(color);
    g.setStroke(stroke);
	g.draw(shape);
	g.setColor(oldColor); 
    g.setStroke(oldStroke);
  }

  public static void fill(Graphics2D g,Shape shape,Color color)
  { if(color==null) return;
	Color oldColor=g.getColor();
    g.setColor(color);
	g.fill(shape);
	g.setColor(oldColor); 
  }

  // ******************************************************************
  // *** METHOD: DrawLine
  // ******************************************************************
  public static void drawLine(Graphics2D g,MapLocation p,MapLocation q)
  { g.drawLine((int)p.getX(),(int)p.getY(),(int)q.getX(),(int)q.getY()); }


  public static Border getTitleBorder(String title)
  { Font boldFont=new Font("Dialog",Font.BOLD,12);
    Border border=new TitledBorder(null,title,TitledBorder.LEFT,TitledBorder.TOP,boldFont);
    return(border);
  }
  
  public static String encodeFloats(float[] f,String none)
  { if(f==null) return(none);
    String s="";
    for(int i=0;i<f.length;i++)
	{ if(i>0) s=s+',';
	  s=s+f[i];
	}
    //Debug.TRACE("Util.encodeFloats: f="+f+", s="+s);
    return(s);
  }
  
  public static float[] decodeFloats(String s,String none)
  { if(s.equalsIgnoreCase(none)) return(null);
    Vector<Float> vector=new Vector<Float>();
    int idx;
    while( (idx=s.indexOf(','))>0)
    { vector.add(new Float(s.substring(0,idx)));
      s=s.substring(idx+1);	
    }
    vector.add(new Float(s));
    int n=vector.size();
    float[] res=new float[n];
    for(int i=0;i<n;i++) res[i]=vector.elementAt(i).floatValue();
	return(res);  
  }

  public static Color getRGBAColor(Color color,float opacity)
  { if(color==null) return(null);
    int r=color.getRed();
	int g=color.getGreen();
	int b=color.getBlue();
	int a=(int)(255*opacity);
	return(new Color(r,g,b,a));
  }
  
  public static String encodeRGB(Color color)
  { // DOC: http://www.w3.org/TR/SVG11/types.html#DataTypeColor
	if(color==null) return("none");
	if(color.equals(Color.black))  return("black");
    if(color.equals(Color.green))  return("green");
    if(color.equals(Color.gray))   return("gray");
    if(color.equals(Color.white))  return("white");
    if(color.equals(Color.yellow)) return("yellow");
    if(color.equals(Color.red))    return("red");
    if(color.equals(Color.blue))   return("blue");
    return("rgb("+color.getRed()+','+color.getGreen()+','+color.getBlue()+')');
  }
 
  public static Color decodeRGB(String rgb)
  { if(rgb==null) return(null);
	if(rgb.equalsIgnoreCase("none"))   return(null);
	if(rgb.equalsIgnoreCase("black"))  return(Color.black);
    if(rgb.equalsIgnoreCase("green"))  return(Color.green);
    if(rgb.equalsIgnoreCase("gray"))   return(Color.gray);
    if(rgb.equalsIgnoreCase("white"))  return(Color.white);
    if(rgb.equalsIgnoreCase("yellow")) return(Color.yellow);
    if(rgb.equalsIgnoreCase("red"))    return(Color.red);
    if(rgb.equalsIgnoreCase("blue"))   return(Color.blue);
    if(rgb.startsWith("rgb"))
    try
    { // rgb(255,255,255)
      String s=rgb.substring(4);	
      int idx=s.indexOf(','); String R=s.substring(0,idx); s=s.substring(idx+1);
      idx=s.indexOf(',');	  String G=s.substring(0,idx); s=s.substring(idx+1);
      idx=s.indexOf(')');	  String B=s.substring(0,idx); s=s.substring(idx+1);
      //Debug.TRACE("Util.decode: R="+R+", G="+G+", B="+B);
      return(new Color(Integer.parseInt(R),Integer.parseInt(G),Integer.parseInt(B)));
    } catch(Exception e) { Debug.EXCEPTION("Util.decode",e); }
	Debug.NOT_IMPLEMENTED("Util.decode: rgb="+rgb);
    return(Color.black); // TODO: TEMP
  }
  

  public static int fillRule(String rule)
  { if(rule.equalsIgnoreCase("nonzero")) return(GeneralPath.WIND_NON_ZERO);
    if(rule.equalsIgnoreCase("evenodd")) return(GeneralPath.WIND_EVEN_ODD);
    throw(new IllegalArgumentException("rule "+rule));
  }

  public static String fillRule(int rule)
  { switch(rule)
	{ case GeneralPath.WIND_NON_ZERO: return("nonzero");
	  case GeneralPath.WIND_EVEN_ODD: return("evenodd");
	  default: throw(new IllegalArgumentException("rule "+rule));
	}
  }


  public static int lineCap(String cap)
  { if(cap.equalsIgnoreCase("butt")) return(BasicStroke.CAP_BUTT);
    if(cap.equalsIgnoreCase("round")) return(BasicStroke.CAP_ROUND);
    if(cap.equalsIgnoreCase("square")) return(BasicStroke.CAP_SQUARE);
    throw(new IllegalArgumentException("cap "+cap));
  }

  public static String lineCap(int cap)
  { switch(cap)
	{ case BasicStroke.CAP_BUTT: return("butt");
	  case BasicStroke.CAP_ROUND: return("round");
	  case BasicStroke.CAP_SQUARE: return("square");
	  default: throw(new IllegalArgumentException("cap "+cap));
	}
  }

  public static int lineJoin(String join)
  { if(join.equalsIgnoreCase("miter")) return(BasicStroke.JOIN_MITER);
    if(join.equalsIgnoreCase("round")) return(BasicStroke.JOIN_ROUND);
    if(join.equalsIgnoreCase("bevel")) return(BasicStroke.JOIN_BEVEL);
    throw(new IllegalArgumentException("join "+join));
  }

  public static String lineJoin(int join)
  { switch(join)
	{ case BasicStroke.JOIN_MITER: return("miter");
	  case BasicStroke.JOIN_ROUND: return("round");
	  case BasicStroke.JOIN_BEVEL: return("bevel");
	  default: throw(new IllegalArgumentException("join "+join));
	}
  }

}
